package com.itserver.utils;

import io.jsonwebtoken.Claims;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.concurrent.TimeUnit;

@Component
public class RedisCache {
    private  final RedisTemplate<String, String> redisTemplate;

    private static final String InvalidTokenList = "InvalidTokenList:";
    private static final String LoginUserMap = "LoginUserMap:";
    // 过期时间 30 分钟
    private static  long EXPIRE_TIME = 30;
    private final Config config;

    public RedisCache(RedisTemplate<String, String> redisTemplate, Config config) {
        this.redisTemplate = redisTemplate;
        EXPIRE_TIME = config.getExpire();
        this.config = config;
    }

    // 失效的 token 列表
    public List<String> getInvalidTokenList() {
        return redisTemplate.opsForSet().members(InvalidTokenList).stream().toList();
    }


    // 添加失效的 token
    public void addInvalidToken(String token) {
        redisTemplate.opsForSet().add(InvalidTokenList, token);
    }

    // 删除失效的 token
    public void deleteInvalidToken(String token) {
        redisTemplate.opsForSet().remove(InvalidTokenList, token);
    }

    // 检查 token 是否失效
    public boolean isTokenExist(String token) {
        if (token == null) {
            return false;
        }
        Boolean isMember = redisTemplate.opsForSet().isMember(InvalidTokenList, token);
        return isMember != null && isMember;
    }

    // 获取在线用户
    public Map<String , String> getLoginUsers(){
        Map<String , String> onlineUsers = new HashMap<>();
        Set<String> keys = redisTemplate.keys(LoginUserMap + "*");
        for (String key : keys) {
            String token = key.substring(LoginUserMap.length());
            // 获取每个键对应的 token
            Claims claims = JwtUtils.parseJWT(token);
            if (claims != null){
                String username = claims.get("username").toString();
                String uuid = claims.get("uuid").toString();
                onlineUsers.put(username+":"+uuid , token);
            }
        }
        return onlineUsers;
    }
    // 获取在线用户列表
    public List<Map <String, Object>> getLoginUserList(){
        List<Map <String, Object>> onlineUsers = new ArrayList<>();
        Set<String> keys = redisTemplate.keys(LoginUserMap + "*");
        for (String token : keys) {
            Map<String, Object> user  = new HashMap<>();
            user.put("token", token.substring(LoginUserMap.length()));
            // 解析 token
            onlineUsers.add(user);
        }
        return onlineUsers;
    }
    // 判断登录用户token是否存在
    public boolean isLoginUserExist(String token) {
        Map<String, String> onlineUsers = getLoginUsers();
        return onlineUsers.containsValue(token);
    }
    // 添加登录用户
    public void addLoginUser(String token, String username) {
        String uuidKey = LoginUserMap + token ;
        redisTemplate.opsForValue().set(uuidKey, "", EXPIRE_TIME, TimeUnit.MINUTES);
    }
    // 根据token 删除登录用户
    public void deleteLoginUserToken(String token) {
        Set<String> keys = redisTemplate.keys(LoginUserMap + "*");
        for (String key : keys) {
            String keyToken = key.substring(LoginUserMap.length());
            if (keyToken.equals(token)) {
                redisTemplate.delete(key);
                // 添加到失效列表
                addInvalidToken(token);
                break;
            }
        }
    }
    // 根据uuid 删除登录用户
    public void deleteLoginUser(String uuid) {
        Set<String> keys = redisTemplate.keys(LoginUserMap + "*");
        for (String key : keys) {
            String token = key.substring(LoginUserMap.length());
            Claims claims = JwtUtils.parseJWT(token);
            if (claims != null && claims.get("uuid").equals(uuid)) {
                redisTemplate.delete(LoginUserMap + token);
                // 加入黑名单
                addInvalidToken(token);
                break;
            }
        }
    }

    // 根据用户名获取 token
    public String getTokenByUsername(String username) {
        List<Map<String, Object>> onlineUsers = getLoginUserList();
        for (Map<String, Object> onlineUser : onlineUsers) {
            String token = onlineUser.get("token").toString();
            Claims claims = JwtUtils.parseJWT(token);
            if (claims != null && claims.get("username").equals(username)) {
                return token;
            }
        }
        return null;
    }
}